Bind
Bind可用于绑定函数、成员函数、函数对象、成员变量,bind函数支持最多10个自定义参数
1 2 3 4
| int f(int a, int b) { return a + b; } std::bind(f, 5, std::placeholders::_1)(x);
|
在上面这段代码中:
- std::bind函数返回绑定对象,后面跟的(x)表示传参x并执行;
- std::placeholders::_1是占位符,表示调用时的第一个参数,这段代码里表示x;
- 如果代码是std::bind(f, std::placeholders::_2, std::placeholders::_1)(x, y)则表示执行f(y, x)
- 调用前传入的函数参数会被复制并保存在std::bind返回的对象中,比如之前的std::bind(f, 5, std::placeholders::_1)中的5就被存储在了返回的对象中,所以为了性能上考虑,建议传入的类型为引用或指针,避免结构复制
Bind和类成员函数
此时需要注意的是成员函数绑定的第二个参数必须是类实例:
1 2 3 4 5 6 7 8 9 10
| struct X { bool f(int a); }; X x; std::shared_ptr<X> p(new X); int i = 5; std::bind(&X::f, ref(x), std::placeholders::_1)(i); std::bind(&X::f, &x, std::placeholders::_1)(i); std::bind(&X::f, x, std::placeholders::_1)(i); std::bind(&X::f, p, std::placeholders::_1)(i);
|
由于第二个参数的类实例的保存方式与参数一致,所以也建议传入类引用或类指针,或者智能指针
bind举例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <iostream> #include <cstdio> #include <memory> #include <functional> class Button { public: std::function<void(int)> onClick; }; class Player{ public: void play(void* sender, int param) { printf("Play: %d => %d\n", (int)sender, param); } void stop(void* sender, int param) { printf("Play: %d => %d\n", (int)sender, param); } }; Button playButton, stopButton; Player thePlayer; void connect() { playButton.onClick = std::Bind(&Player::play, &thePlayer, &playButton, std::placeholders::_1); stopButton.onClick = std::Bind(&Player::stop, &thePlayer, &stopButton, std::placeholders::_1); } int main() { connect(); playButton.onClick(0); return 0; }
|
上面这段程序其实就是bind在回调函数中的用法,Button类中有一个回调函数onClick(),需要根据不同的场合实现不同的功能,使用bind函数为playButton绑定了play()函数,而为stopButton绑定了stop()函数,这是bind()函数在回调这方面的一个典型用法。